package com.hb.trade.api.routine.controller.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.hb.core.pojo.JSONObjectProperty;
import com.hb.core.pojo.project.section.dto.BidSectionDTO;
import com.hb.trade.api.routine.client.ImClient;
import com.hb.trade.api.routine.config.aspect.RsaDecrypt;
import com.hb.trade.api.routine.config.pay.AliPayConfig;
import com.hb.trade.api.routine.config.pay.WeixinPayConfig;
import com.hb.trade.client.project.SectionClient;
import fzzn.core.spire.OfficeUtil;
import lombok.Getter;
import lombok.Setter;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.fzzn.core.file.service.DownloadService;
import org.fzzn.core.model.constant.CommonConstant;
import org.fzzn.core.model.enums.WebsocketMsgEnum;
import org.fzzn.core.model.msg.Message;
import org.fzzn.core.model.msg.ResponseDto;
import org.fzzn.core.model.websocket.SocketMessageEntity;
import org.fzzn.core.service.ZipFileService;
import org.fzzn.core.util.ResultUtil;
import org.fzzn.core.web.anno.Version;
import org.fzzn.core.web.util.SpringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

@RestController
@Version(1.0)
@RequestMapping("/{version}")
public class ApiTestController {

    protected final DownloadService downloadService;
    protected final ImClient imClient;
    protected final SectionClient sectionClient;

    @Value("${hb.opera-time:1000}")
    private Integer operaTime;

    public ApiTestController(DownloadService downloadService,
                             ImClient imClient,
                             SectionClient sectionClient) {
        this.downloadService = downloadService;
        this.imClient = imClient;
        this.sectionClient = sectionClient;
    }

    @RsaDecrypt(paramKeyName = "aaa")
    @RequestMapping("/test/remote")
    public String testRemote() {
        return "operaTime: " + operaTime;
    }

    /**
     * 测试ZipFileService对文件的读取
     *
     * @param filePath
     * @return
     */
    @RequestMapping("/test/zipService")
    public ResponseDto<?> testZipService(String filePath) {
        if (StrUtil.isEmpty(filePath)) {
            return ResultUtil.FAIL;
        }
        File file = new File(filePath);
        if (!FileUtil.exist(file)) {
            return ResultUtil.fail("file not exists ! " + filePath);
        }

        ZipFileService instance;
        try {
            instance = ZipFileService.getInstance(file);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.fail(e.getMessage());
        }

        List<String> names = instance.names();

        List<String> files = CollUtil.list(false);

        for (String name : names) {
            File itemFile = instance.getItemFile(name);
            files.add(itemFile.getAbsolutePath());
        }
        names.addAll(files);
        return ResultUtil.msg(true, names);
    }

    /**
     * 测试ZipFileService对文件的读取
     *
     * @param filePath
     * @return
     */
    @RequestMapping("/test/zipService/readItem")
    public void testZipServiceReadItem(String filePath, String itemName) {
        if (StrUtil.isEmpty(filePath)) {
            return;
        }
        File file = new File(filePath);
        if (!FileUtil.exist(file)) {
            return;
        }

        ZipFileService instance;
        try {
            instance = ZipFileService.getInstance(file);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }
        File itemFile = instance.getItemFile(itemName);
        downloadService.download(itemFile);
    }

    /**
     * 测试imClient的调用
     *
     * @return
     */
    @RequestMapping("/test/im/info")
    public ResponseDto<?> testImInfo() {
        return imClient.imInfo(SocketMessageEntity.getInstance("1234345632", WebsocketMsgEnum.IM));
    }

    /**
     * 测试日期格式数据的传输
     *
     * @param section
     * @return
     */
    @RsaDecrypt(paramKeyName = "projectName")
    @RequestMapping("/test/datetime")
    public ResponseDto<?> testDatetime(@RequestBody BidSectionDTO section) {
        System.out.println(section.getProjectName());
        Message<BidSectionDTO> bidSection = sectionClient.getBidSection(section);
        return ResultUtil.msg(bidSection);
    }

    /**
     * 测试支付回调地址的读取
     * 支持动态实时修改
     *
     * @return
     */
    @RequestMapping("/test/notify")
    public String testNotify() {
        List<String> ns = CollUtil.list(false);
        ns.add(AliPayConfig.notifyUrl());
        ns.add(AliPayConfig.notifyPage());
        ns.add(WeixinPayConfig.notifyUrl());
        return ns.toString();
    }

    /**
     * 测试html转word, 同时去除Spire水印
     *
     * @param file
     * @return
     * @throws IOException
     */
    @RequestMapping("/test/aspose")
    public ResponseDto<?> testAspose(MultipartFile file) throws IOException {
        if (file == null) {
            return ResultUtil.FAIL;
        }
        String originalFilename = file.getOriginalFilename();
        if (StrUtil.isEmpty(originalFilename)) {
            return ResultUtil.FAIL;
        }
        File tempFile = new File(CommonConstant.TEMP_PATH + "/" + file.getOriginalFilename());
        FileUtil.writeBytes(file.getBytes(), tempFile);

        File htmlToWordFile = OfficeUtil.htmlStrToWordFile(FileUtil.readUtf8String(tempFile), null);
        File removeSpireDocWaterFile = OfficeUtil.removeSpireDocWater(htmlToWordFile);

        return ResultUtil.msg(200, removeSpireDocWaterFile.getAbsolutePath());
    }

    /**
     * 测试shiro访问权限控制
     *
     * @return
     */
    @RequestMapping("/test/localFile")
    public ResponseDto<?> localFile() {
        JSONObject obj = JSONUtil.createObj();

        File localFile = SpringUtils.getLocalFile("template/pingbiaobaogaomoban.xlsx");
        if (FileUtil.exist(localFile)) {
            obj.set("exists", localFile.exists());
            obj.set("path", localFile.getAbsolutePath());
            obj.set("length", localFile.length());
        }

        InputStream stream = SpringUtils.getLocalStream("template/pingbiaobaogaomoban.xlsx");
        if (stream != null) {
            obj.set("stream", IoUtil.readBytes(stream));
        }

        return ResultUtil.msg(true, obj);
    }

    /**
     * 测试shiro访问权限控制
     *
     * @return
     */
    @RequestMapping("/shiro/visitable")
    public ResponseDto<?> shiroVisitable() {
        Subject subject = SecurityUtils.getSubject();
        return ResultUtil.msg(true, subject);
    }

    /**
     * jsonInfo
     *
     * @return
     */
    @RequestMapping("/test/jsonInfo")
    public ResponseDto<?> testJsonInfo(@RequestBody TestEntity test) {
        return ResultUtil.msg(true, test);
    }
}

@Setter
@Getter
class TestEntity {
    private JSONObjectProperty entity;
    private String name;
}
